package com.settlement.system.parse.formula;

/**
 * 等式比较
 *
 * @author Ximi
 * @since 2020/10/10
 */
public class EqualsCalculator implements Calculator<Boolean> {

    private PlaceHoldParse placeHoldParse;
    private String[] splits = new String[]{"<>", ">=", "<=", ">", "<", "="};

    final String NOT_EQ = "<>";
    final String GREATER_EQ = ">=";
    final String LESS_EQ = "<=";
    final String GREATER = ">";
    final String LESS = "<";
    final String EQUAL = "=";

    public EqualsCalculator(PlaceHoldParse placeHoldParse) {
        this.placeHoldParse = placeHoldParse;
    }

    @Override
    public Boolean calculate(String formula) {

        String[] formulas = null;
        String opt = null;
        for (int index = 0; index < splits.length; index++) {
            if (formula.contains(splits[index])) {
                formulas = formula.split(splits[index]);
                opt = splits[index];
                break;
            }
        }

        if (formulas == null) {
            return false;
        }

        Calculator<? extends Comparable> calculator = getCalculator(formula);

        Comparable rightResult = calculator.calculate(formulas[0]);
        Comparable leftResult = calculator.calculate(formulas[1]);

        if (NOT_EQ.equals(opt)) {
            return rightResult.compareTo(leftResult) != 0;
        }

        if (GREATER_EQ.equals(opt)) {
            return rightResult.compareTo(leftResult) >= 0;
        }

        if (LESS_EQ.equals(opt)) {
            return rightResult.compareTo(leftResult) <= 0;
        }

        if (GREATER.equals(opt)) {
            return rightResult.compareTo(leftResult) > 0;
        }

        if (LESS.equals(opt)) {
            return rightResult.compareTo(leftResult) < 0;
        }

        if (EQUAL.equals(opt)) {
            return rightResult.compareTo(leftResult) == 0;
        }

        return false;
    }

    public Calculator<? extends Comparable> getCalculator(String formula) {

        if (formula.contains(OrderPlaceHoldEunm.searchDate.getName())
                || formula.contains(OrderPlaceHoldEunm.businessDate.getName())
                || formula.contains(OrderPlaceHoldEunm.today.getName())
                || formula.contains("y")
                || formula.contains("m")
                || formula.contains("d")) {
            return new DateCalculator(placeHoldParse);
        }

        return new NumberCalculator(placeHoldParse);
    }

}
